/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */
#pragma once

#include <xml/Object.h>
#include <Color.h>
#include "Texture.h"
#include <animate/Node.h>
#include "Material.h"
#include <lib3d/anim2d/AnimatedSequences.h>
#include <CompilerFeatures.h>
#include <boost/scoped_ptr.hpp>

namespace liba {
namespace lib3d {
namespace material {

class Shader : public xml::ObjectANSI, public animate::Node, private NoAssign
{
public:
	Shader();
	Shader(const Shader & other);
	explicit Shader(const Atom & name);
	virtual ~Shader();
	void render_to_list( hard::Hardware * hardware, hard::RenderMaterial * render_material );

	// Attributes
	static const Atom transparency_name;
	static const Atom specular_power_name;
	static const Atom diffuse_name;
	static const Atom reflection_name;
	static const Atom reflectivity_name;
	static const Atom emissive_name;
	static const Atom specular_name;
	// Nodes
	static const Atom diffuse_texture_name;
	static const Atom bump_texture_name;
	static const Atom emissive_texture_name;
	static const Atom cubic_reflection_texture_name;
	static const Atom randomizeName;

	virtual animate::Node * FindAnimateNode(const Atom & name, bool recursion) LIBA_OVERRIDE;

	int get_triangles_count()const
	{
		return triangles_count;
	}
	int get_vertex_count()const
	{
		return vertex_count;
	}
	double get_transparency()const
	{
		return material.transparency;
	}
	void set_color(const Color& value)
	{
		this->material.emissive = value;
	}
	void set_transparency(double value)
	{
		this->material.transparency = value;
	}
private:
	Material material;
	boost::scoped_ptr<Texture> diffuse_texture;
	boost::scoped_ptr<Texture> bump_texture;
	boost::scoped_ptr<Texture> emissive_texture;
	boost::scoped_ptr<Texture> cubic_reflection_texture;

	//sequence code
	boost::scoped_ptr<anim2d::AnimatedSequences> emissive_sequence;

	bool SuperPuperMegaEmissiveAlphaMutilplyByAlphaBug;

	int triangles_count;
	int vertex_count;
protected:
	virtual bool on_attribute(xml::Provider *prov, const std::string & name, const std::string & value ) LIBA_OVERRIDE;
	virtual bool on_node(xml::Provider * prov, const std::string & name ) LIBA_OVERRIDE;
	virtual void on_save_attributes( xml::SaverBase * saver )const LIBA_OVERRIDE;
	virtual void on_save_nodes( xml::SaverBase * saver )const LIBA_OVERRIDE;
private:
	properties::VirtualDependencyProperty<double> transparency;

	math::Vector3<float> GetDiffuse();
	void SetDiffuse(math::Vector3<float> value);
	properties::VirtualDependencyPropertyByValue<math::Vector3<float> > diffuse;

	math::Vector3<float> GetReflection();
	void SetReflection(math::Vector3<float> value);
	properties::VirtualDependencyPropertyByValue<math::Vector3<float> > reflection;

	math::Vector3<float> GetEmissive();
	void SetEmissive(math::Vector3<float> value);
	properties::VirtualDependencyPropertyByValue<math::Vector3<float> > emissive;

	void RandomizeCommand();
	properties::Command<> randomize;
};

} // namespace material
} // namespace lib3d
} // namespace liba
using namespace liba;

